﻿using JustMetClient.Commons;
using JustMetClient.Models.InfoModels;
using JustMetClient.Models.WebApiModels;
using JustMetClient.Modules.WebModule;
using Azylee.Core.AppUtils;
using Azylee.Core.DataUtils.CollectionUtils;
using Azylee.Core.DataUtils.DateTimeUtils;
using Azylee.Core.ThreadUtils.SleepUtils;
using Azylee.Core.WindowsUtils.APIUtils;
using Azylee.Core.WindowsUtils.InfoUtils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace JustMetClient.Modules.ComputerStatusModule
{
    public static class ComputerStatusMonitor
    {
        private static long AFK = 0;//脱机时长
        private static int Cpu = 0;//CPU占用
        private static long Ram = 0;//系统可用内存
        private static long SysDisk = 0;//系统盘可用空间
        private static int AppCpu = 0;//程序CPU占用
        private static TimeSpan Pin = TimeSpan.Zero;//程序运行时间戳
        private static DateTime CPUHighSendTime = DateTime.MinValue;//CPU高信息的发送时间
        private static DateTime WorkHardSendTime = DateTime.MinValue;//努力工作计算机信息发送时间
        private static DateTime UseLowSendTime = DateTime.MinValue;//非常空闲的电脑信息发送时间

        private static int CpuHighTimes = 0, CpuHighLine = 80, CpuHighTimesMax = 60;
        private static int AppCpuHighTimes = 0, AppCpuHighLine = 20, AppCpuHighTimesMax = 30;
        private static int WorkHardInNight = 0, WorkHardAFKLine = 1000, WorkHardMaxTime = 300;
        private static long UseLowLine = 1 * 60 * 60 * 1000;

        private static CancellationTokenSource Token = new CancellationTokenSource();//任务运行标记
        private static Process AppProcess = Process.GetCurrentProcess();//当前进程监控
        private static PerformanceCounter ComputerProcessor = ComputerStatusTool.Processor();//电脑CPU监控
        public static void Start()
        {
            try
            {
                Task.Factory.StartNew(() =>
                {
                    while (!Token.IsCancellationRequested)
                    {
                        try
                        {
                            Do();
                            CpuMonitor();
                            WorkHardMonitor();
                            UseLowMonitor();
                            Sleep.S(1);
                        }
                        catch { }
                    }
                });
            }
            catch { }
        }
        private static void Do()
        {
            try { Cpu = (int)ComputerProcessor.NextValue(); } catch { }
            AFK = WindowsAPI.GetLastInputTime();
            Ram = (long)ComputerInfoTool.AvailablePhysicalMemory();
            SysDisk = ComputerInfoTool.GetSystemDriveAvailableSize();
            AppCpu = (int)AppInfoTool.CalcCpuRate(AppProcess, ref Pin, 1000);
        }
        /// <summary>
        /// 监控CPU占用情况，收集到服务端
        /// </summary>
        private static void CpuMonitor()
        {
            if (Cpu > CpuHighLine) CpuHighTimes++; else CpuHighTimes--;
            if (CpuHighTimes < 0) CpuHighTimes = 0;

            if (AppCpu > AppCpuHighLine) AppCpuHighTimes++; else AppCpuHighTimes--;
            if (AppCpuHighTimes < 0) AppCpuHighTimes = 0;

            if (CpuHighTimes > CpuHighTimesMax || AppCpuHighTimes > AppCpuHighTimesMax)
            {
                if (DateTime.Now > CPUHighSendTime.AddMinutes(10))
                {
                    WebApiSendQueue.Add(R.Web.Send.ClientCollection, new ClientUserDefinedInfoModel()
                    {
                        Type = "计算机CPU和客户端CPU占用高",
                        Values = ArrayTool.Formatter(new string[] { R.UserName, $"{AFK}", $"{Cpu}", $"{Ram}", $"{SysDisk}", $"{AppCpu}", CpuHighTimes.ToString(), AppCpuHighTimes.ToString() }, "", 10),
                    }, HttpMethodType.Post);

                    CPUHighSendTime = DateTime.Now;
                    CpuHighTimes = 0;
                    AppCpuHighTimes = 0;
                }
            }
        }
        /// <summary>
        /// 工作努力的计算机
        /// </summary>
        private static void WorkHardMonitor()
        {
            //夜间-次日早晨
            if (DateTime.Now.Hour > 20 || DateTime.Now.Hour < 6)
            {
                if (AFK < WorkHardAFKLine) WorkHardInNight++;

                if (WorkHardInNight > WorkHardMaxTime)
                {
                    if (DateTime.Now > WorkHardSendTime.AddMinutes(10))
                    {
                        WebApiSendQueue.Add(R.Web.Send.ClientCollection, new ClientUserDefinedInfoModel()
                        {
                            Type = "非工作时间努力工作",
                            Values = ArrayTool.Formatter(new string[] { R.UserName, $"{AFK}", WorkHardInNight.ToString(), $"{WeekDayTool.ToWeekDay(DateTime.Now)}", $"{R.DeptNo}", $"{R.Dept}" }, "", 10),
                        }, HttpMethodType.Post);

                        WorkHardSendTime = DateTime.Now;
                        WorkHardInNight = 0;
                    }
                }
            }
        }
        /// <summary>
        /// 空闲时间过长的电脑
        /// </summary>
        private static void UseLowMonitor()
        {
            long afk_warning_time = 1 * 60 * 60 * 1000;
            if (DateTime.Now > UseLowSendTime.AddMilliseconds(afk_warning_time) && AFK > UseLowLine)
            {
                WebApiSendQueue.Add(R.Web.Send.ClientCollection, new ClientUserDefinedInfoModel()
                {
                    Type = "空闲电脑-自定时长",
                    Values = ArrayTool.Formatter(new string[] { R.UserName, $"{AFK}", $"{afk_warning_time}", $"{WeekDayTool.ToWeekDay(DateTime.Now)}", $"{R.DeptNo}", $"{R.Dept}" }, "", 10),
                }, HttpMethodType.Post);

                UseLowSendTime = DateTime.Now;
            }
        }
    }
}
